package chalmers.game.subterranean.model.world.squares;

import chalmers.game.subterranean.util.Resource;
import chalmers.game.subterranean.model.world.squares.blocks.ISquareType;
import chalmers.game.subterranean.model.world.squares.blocks.digblocks.Air;
import chalmers.game.subterranean.util.BlockType;

public class Square implements ISquare {

  private static final ISquareType voidType = new Air(); // A shared Air for all Squares.
  private final ISquareType mainType;
  private ISquareType activeType;

  /**
   * Give the type of Square you want, if null is given, an Air will be created.
   * 
   * @param block
   */
  public Square(ISquareType block) {
    if (block == null || block.handleGetType().equals(voidType.handleGetType())) {
      mainType = voidType;
    } else {
      mainType = block;
    }
    activeType = mainType;
  }

  /**
   * This will damage a specific block for the amount specified in damage parameter.
   * 
   * @param damage
   * @return Nothing if the block didn't break and the corresponding Item if the block did break.
   */
  @Override
  public Resource dig(double damage) {
    Resource rI = activeType.handleDig(damage);
    if (rI == null) {
      return Resource.NOTHING;
    } else {
      makeVoid();
      return rI;
    }
  }

  /**
   * @return true if player can walk through the Square
   */
  @Override
  public boolean pressAgainst() {
    return activeType.handlePressAgainst();
  }

  /**
   * @return the current type of the Square
   */
  @Override
  public BlockType getType() {
    return activeType.handleGetType();
  }

  /**
   * Mostly for testing
   * 
   * @return how much damage this Square can take before breaking
   */
  @Override
  public float getDurability() {
    return this.activeType.handleGetDurability();
  }

  /**
   * In the end of this call chain most of the times an Event will be sent. Example: Open shop,
   * Close Shop, etc
   */
  @Override
  public void action() {
    this.activeType.handleAction();
  }

  private void makeVoid() {
    activeType = voidType;
  }
}
